{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 使用Syft Keras进行隐私预测"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 步骤3：使用Syft Keras进行隐私预测-服务（客户端）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "恭喜你！ 用普通的Keras训练模型并用Syft Keras固定模型后，您就可以请求一些隐私预测了。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.datasets import mnist\n",
    "\n",
    "import syft as sy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在这里，我们预处理MNIST数据。这与我们在训练期间进行预处理的方式相同。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 输入图像的维度\n",
    "img_rows, img_cols = 28, 28\n",
    "\n",
    "# 数据拆分成训练数据和测试数据\n",
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "\n",
    "x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)\n",
    "x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)\n",
    "input_shape = (img_rows, img_cols, 1)\n",
    "\n",
    "x_train = x_train.astype('float32')\n",
    "x_test = x_test.astype('float32')\n",
    "x_train /= 255\n",
    "x_test /= 255"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 连接模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在查询模型之前，您只需连接到它。 为此，您可以创建一个客户端。 然后定义完全相同的三个TFEWorkers（`alice`，`bob`和`carol`）并进行聚类。最后调用`connect_to_model`。 这将在客户端上创建一个TFE排队服务器，该服务器连接到**Part 13b**中的`model.serve（）`设置的排队服务器。队列将负责在预测请求中提交共享之前秘密共享明文数据。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_classes = 10\n",
    "input_shape = (1, 28, 28, 1)\n",
    "output_shape = (1, num_classes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tf_encrypted:Starting session on target 'grpc://localhost:4000' using config graph_options {\n",
      "}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "client = sy.TFEWorker()\n",
    "\n",
    "alice = sy.TFEWorker(host='localhost:4000')\n",
    "bob = sy.TFEWorker(host='localhost:4001')\n",
    "carol = sy.TFEWorker(host='localhost:4002')\n",
    "cluster = sy.TFECluster(alice, bob, carol)\n",
    "\n",
    "client.connect_to_model(input_shape, output_shape, cluster)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 查询模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "您已准备好进行一些隐私预测！调用query_model将把image插入到上面创建的队列中，在本地秘密共享数据，并将共享分片提交给**Part 13b**中的模型服务器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 用户输入\n",
    "num_tests = 3\n",
    "images, expected_labels = x_test[:num_tests], y_test[:num_tests]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The image had label 7 and was correctly classified as 7\n",
      "The image had label 2 and was correctly classified as 2\n",
      "The image had label 1 and was correctly classified as 1\n"
     ]
    }
   ],
   "source": [
    "for image, expected_label in zip(images, expected_labels):\n",
    "\n",
    "    res = client.query_model(image.reshape(1, 28, 28, 1))\n",
    "    predicted_label = np.argmax(res)\n",
    "\n",
    "    print(\"The image had label {} and was {} classified as {}\".format(\n",
    "        expected_label,\n",
    "        \"correctly\" if expected_label == predicted_label else \"wrongly\",\n",
    "        predicted_label))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这很棒。您可以正确分类这三个图像！但是，这些预测的特别之处在于您尚未透露任何隐私信息来获取此服务。模型主机从未看到您的输入数据或预测，也从未下载过模型。您可以使用加密模型获得对加密数据的隐私预测！\n",
    "\n",
    "在我们急于将其应用到自己的应用程序中之前，让我们快速回到**Part 13b**来清理我们提供的模型！"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": false,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
